//
//  XS_BaseViewController.swift
//  
//
//  Created by 韩云智 on 2021/10/4.
//

import UIKit
import RxCocoa
import RxSwift
import Toast

open class XS_BaseViewController: UIViewController {
    open lazy var disposeBag = DisposeBag()
    
    // MARK: - 转屏
    open override var shouldAutorotate: Bool { Base_hanyz.shouldAutorotate }
    open override var supportedInterfaceOrientations: UIInterfaceOrientationMask { Base_hanyz.supportedInterfaceOrientations }
    open override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
        switch supportedInterfaceOrientations {
        case .portrait: return .portrait
        case .portraitUpsideDown: return .portraitUpsideDown
        case .landscapeLeft:
            XS_BaseViewController._defaultLandscape = .landscapeLeft
            return .landscapeLeft
        case .landscapeRight:
            XS_BaseViewController._defaultLandscape = .landscapeRight
            return .landscapeRight
        case .landscape:
            switch UIDevice.current.orientation {
            case .landscapeRight:
                XS_BaseViewController._defaultLandscape = .landscapeLeft
                return .landscapeLeft
            case .landscapeLeft:
                XS_BaseViewController._defaultLandscape = .landscapeRight
                return .landscapeRight
            default: return XS_BaseViewController._defaultLandscape
            }
        default:
            let ori = UIApplication.shared.statusBarOrientation
            if ori == .landscapeLeft || ori == .landscapeRight {
                XS_BaseViewController._defaultLandscape = ori
            }
            return ori
        }
    }
    private static var _defaultLandscape: UIInterfaceOrientation = UIInterfaceOrientation.landscapeRight
    
    // MARK: - 生命周期
    deinit {
#if DEBUG
        print("deinit: \(type(of: self))")
#endif
    }
    // 需要在初始化时,进行的操作
    open func upConfig() {}
    open func upView() {}
    open func getViewColor() -> UIColor? { Base_hanyz.backgroundColor }
    public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
#if DEBUG
        print("init: \(type(of: self))")
#endif
        upConfig()
    }
    required public init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    open override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = getViewColor()
        upView()
    }
    
    //MARK: - 导航条
    open func hideBackTitle() {
        navigationItem.backBarButtonItem = UIBarButtonItem(title: nil, style: .plain, target: nil, action: nil)
    }
    /// 隐藏导航条
    open lazy var shouldNavBarHidden: Bool = Base_hanyz.shouldNavBarHidden
    /// 状态栏颜色
    open lazy var isStatusBarBlack: Bool = Base_hanyz.isStatusBarBlack {
        didSet { setNeedsStatusBarAppearanceUpdate() }
    }
    open override var preferredStatusBarStyle: UIStatusBarStyle {
        if #available(iOS 13.0, *) {
            return isStatusBarBlack ? UIStatusBarStyle.darkContent : UIStatusBarStyle.lightContent
        } else {
            return isStatusBarBlack ? UIStatusBarStyle.default : UIStatusBarStyle.lightContent
        }
    }
    open override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        // 隐藏/展示导航条的操作
        if navigationController?.navigationBar.isHidden != shouldNavBarHidden {
            navigationController?.setNavigationBarHidden(shouldNavBarHidden, animated: animated)
        }
    }
    
    //MARK: - 处理 ViewModel 默认事件
    private var _loadingDisposable: Disposable?
    open func loadVMAction(_ vm: XS_BaseViewModel, completion: ((XS_VMActionType) -> Bool)? = nil) {
        vm.actionPS.subscribe(onNext: { [weak self] type in
            if let completion = completion, completion(type) { return }
            guard let `self` = self else { return }
            switch type {
            case let .activity(isEnabled, hasLoading):
                self.view.isUserInteractionEnabled = isEnabled
                self._loadingDisposable?.dispose()
                if isEnabled {
                    self.view.hideToastActivity()
                } else if hasLoading {
                    self._loadingDisposable = Observable.just(()).delay(RxTimeInterval.milliseconds(Int(ceil(ToastManager.shared.style.fadeDuration*1000))+2), scheduler: MainScheduler.asyncInstance)
                        .subscribe(onNext: { [weak self] in
                            guard let `self` = self, !self.view.isUserInteractionEnabled else { return }
                            self.view.makeToastActivity(ToastPosition.center)
                        })
                }
            case let .show(msg, position):
                self.view.xsToast(msg, position: position)
            case let .present(vc, animated, completion):
                self.present(vc, animated: animated, completion: completion)
            case let .dismiss(animated, completion):
                if let nvc = self.navigationController {
                    nvc.dismiss(animated: animated, completion: completion)
                } else {
                    self.dismiss(animated: animated, completion: completion)
                }
            case let .push(vc, animated):
                self.navigationController?.pushViewController(vc, animated: animated)
            case let .popViewController(animated):
                self.navigationController?.popViewController(animated: animated)
            case let .popToViewController(viewController, animated):
                self.navigationController?.popToViewController(viewController, animated: animated)
            case let .popToRootViewController(animated):
                self.navigationController?.popToRootViewController(animated: animated)
            }
        }).disposed(by: disposeBag)
    }
    
    //MARK: - 监听键盘改变
    open func observeKeyboard(_ changeBlock: ((TimeInterval, CGRect)->Void)? = nil) {
        let changeBlock = changeBlock ?? { [weak self] duration, rect in
            guard let `self` = self else { return }
            UIView.animate(withDuration: duration) {
                self.view.frame.size.height = rect.origin.y
            }
        }
        NotificationCenter.default.rx
            .notification(UIResponder.keyboardWillChangeFrameNotification)
            .subscribe(onNext: { [weak self] noti in
                guard let `self` = self,
                      let duration = noti.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval,
                      let endValue = noti.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { return }
                changeBlock(duration, self.view.convert(endValue.cgRectValue, from: UIApplication.shared.windows.last))
            }).disposed(by: disposeBag)
    }
}
